package cn.tangcent.rules;

import cn.tangcent.*;

import java.util.Arrays;

/**
 * Created by TangMing on 2017/4/8.
 * 抽象规则：分成九组，分别对每组进行校验
 */
public abstract class PartitionRule implements SudokuRule {

    //cache previous
    private int group = 0;//组号

    //当前标记
    //optionsFlags[i] = j
    //j=-1:没有空格可以填i
    //j=-2:超过一个空格可以填i
    //j=other:j处填i
    protected int[] optionsFlags = new int[9];

    @Override
    public boolean check(SudokuData sudokuData) {
        boolean result = false;
        for (int i = 0; i < 9; i++) {
            //该组已填写完毕
            int selected = selected(sudokuData, i);
            if (SudokuUtils.all(selected))
                continue;

            Arrays.fill(optionsFlags, -1);
            int rGroup = SudokuUtils.shift(i, group);
            check(sudokuData, rGroup, selected);
            for (int j = 0; j < 9; j++) {
                if (optionsFlags[j] != -1 && optionsFlags[j] != -2) {
                    if (!result) {
                        result = true;
                        group = SudokuUtils.shift(rGroup, 1);
                    }
                    Value value = new Value(j + 1, SudokuUtils.index2XY(optionsFlags[j]));
                    sudokuData.sure(value);
                    SudokuUtils.print("\n" + getClass().getSimpleName() + " sure:" + value.toString()
                            + "\noptionsFlags:" + Arrays.toString(optionsFlags));
                }
            }
        }
        return result;
    }

    protected void setFlag(int number, Coordinate coordinate) {
        switch (optionsFlags[number]) {
            case -1:
                optionsFlags[number] = SudokuUtils.toIndex(coordinate);
                break;
            case -2:
                break;
            default:
                optionsFlags[number] = -2;//multi
                break;
        }
    }

    public abstract int selected(SudokuData sudokuData, int num);

    public abstract void check(SudokuData sudokuData, int num, int selected);
}
